
package nio.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class Client {
	 /*标识数字*/  
    private static int flag = 0;  
    /*缓冲区大小*/  
    private static int BLOCK = 4096;  
    /*接受数据缓冲区*/  
    private static ByteBuffer sendbuffer = ByteBuffer.allocate(BLOCK);  
    /*发送数据缓冲区*/  
    private static ByteBuffer receivebuffer = ByteBuffer.allocate(BLOCK);  
    /*服务器端地址*/  
    private final static InetSocketAddress SERVER_ADDRESS = new InetSocketAddress(  
            "localhost", 5222);  
    Selector selector;
    
    public Client() throws IOException{
    	 // TODO Auto-generated method stub  
        // 打开socket通道  
        SocketChannel socketChannel = SocketChannel.open();  
        // 设置为非阻塞方式  
        socketChannel.configureBlocking(false);  
        // 打开选择器  
        selector = Selector.open();  
        // 注册连接服务端socket动作  
        socketChannel.register(selector, SelectionKey.OP_CONNECT);  
        // 连接  
        socketChannel.connect(SERVER_ADDRESS);  
    }
    
    
    public void Connection(Selector selector) throws IOException{
        
        Set<SelectionKey> selectionKeys;  
        Iterator<SelectionKey> iterator;  
        SelectionKey selectionKey;  
        SocketChannel client;  
        String receiveText;  
        String sendText;  
        int count=0;  
  
        while (true) {  
            //选择一组键，其相应的通道已为 I/O 操作准备就绪。  
            //此方法执行处于阻塞模式的选择操作。  
            selector.select();  
            //返回此选择器的已选择键集。  
            selectionKeys = selector.selectedKeys();  
            //System.out.println(selectionKeys.size());  
            iterator = selectionKeys.iterator();  
            while (iterator.hasNext()) {  
                selectionKey = iterator.next();  
                if (selectionKey.isConnectable()) {  
                    System.out.println("client connect");  
                    client = (SocketChannel) selectionKey.channel();  
                    // 判断此通道上是否正在进行连接操作。  
                    // 完成套接字通道的连接过程。  
                    if (client.isConnectionPending()) {  
                        client.finishConnect();  
                        System.out.println("完成连接!");  
                        sendbuffer.clear();  
                        sendbuffer.put("Hello,Server".getBytes());  
                        sendbuffer.flip();  
                        client.write(sendbuffer);  
                    }  
                    client.register(selector, SelectionKey.OP_READ);  
                } else if (selectionKey.isReadable()) {  
                    client = (SocketChannel) selectionKey.channel();  
                    //将缓冲区清空以备下次读取  
                    receivebuffer.clear();  
                    //读取服务器发送来的数据到缓冲区中  
                    count=client.read(receivebuffer);  
                    if(count>0){    
                        receiveText = new String( receivebuffer.array(),0,count);  
                        System.out.println("客户端接受服务器端数据--:"+receiveText);  
                        client.register(selector, SelectionKey.OP_WRITE);  
                    }  
  
                } else if (selectionKey.isWritable()) {  
                    sendbuffer.clear();  
                    client = (SocketChannel) selectionKey.channel();  
                   // sendText = "message from client--" + (flag++);
                    BufferedReader strin=new BufferedReader(new InputStreamReader(System.in));
                    sendText= strin.readLine();
                    sendbuffer.put(sendText.getBytes());  
                     //将缓冲区各标志复位,因为向里面put了数据标志被改变要想从中读取数据发向服务器,就要复位  
                    sendbuffer.flip();  
                    client.write(sendbuffer);  
                    System.out.println("客户端向服务器端发送数据--："+sendText);  
                    client.register(selector, SelectionKey.OP_READ);  
                }  
            }  
            selectionKeys.clear();  
        }  
    }
    
    public static void main(String[] args) throws IOException {  
    	
    	ExecutorService exec = Executors.newFixedThreadPool(50);  
    	

	    for(int index = 0; index < 50; index++) {
	    Runnable run = new Runnable() {
		    public void run() {
		   
			    Client client;
				try {
					client = new Client();
					 client.Connection(client.selector);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
		   
		    }
	    };
	    exec.execute(run);
	    }
	    // must shutdown
	    exec.shutdown();
    }  
    
    
}
